﻿#region Using References

using System;
using System.Collections.Generic;
using Beaker.OpenCube.Textures;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace Beaker.OpenCube.Specs.Textures
{
	[TestClass]
	public class FrameInfoSpecs
	{
		#region Parse

		[TestMethod]
		public void ParseOfNullStringShouldThrowArgumentNullExceptoin()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			Action act = () => FrameInfo.TryParse( null, out result );

			// assert
			act.ShouldThrow<ArgumentNullException>();
		}

		[TestMethod]
		public void ParseOfEmptyStringResultsInSuccessButWithNullResult()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( string.Empty, out result );

			// assert
			success.Should().Be( true );
			result.Should().BeNull();
		}

		[TestMethod]
		public void ParseWithCommaResultsInTwoFrames()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "1,0", out result );

			// assert
			success.Should().Be( true );
			result.Should().Equal( new FrameInfo( 1 ), new FrameInfo( 0 ) );
		}

		[TestMethod]
		public void ParseWithNewLineResultsInTwoFrames()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "1\n0", out result );

			// assert
			success.Should().Be( true );
			result.Should().Equal( new FrameInfo( 1 ), new FrameInfo( 0 ) );
		}

		[TestMethod]
		public void ParseWithCariageReturnResultsInTwoFrames()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "1\r0", out result );

			// assert
			success.Should().Be( true );
			result.Should().Equal( new FrameInfo( 1 ), new FrameInfo( 0 ) );
		}

		[TestMethod]
		public void ParseWithNewLineAndCariageReturnResultsInTwoFrames()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "1\r\n0", out result );

			// assert
			success.Should().Be( true );
			result.Should().Equal( new FrameInfo( 1 ), new FrameInfo( 0 ) );
		}

		[TestMethod]
		public void ParseWithAsteriksResultInRepeatCount()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "1*2,0*1", out result );

			// assert
			success.Should().Be( true );
			result.Should().Equal( new FrameInfo( 1, 2 ), new FrameInfo( 0, 1 ) );
		}

		[TestMethod]
		public void InvalidNumberShouldReturnFalseForSuccess()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "foobar", out result );

			// assert
			success.Should().BeFalse();
		}

		[TestMethod]
		public void InvalidFrameNumberShouldReturnFalseForSuccess()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "foo*2", out result );

			// assert
			success.Should().BeFalse();
		}

		[TestMethod]
		public void InvalidRepeatNumberShouldReturnFalseForSuccess()
		{
			// arrange
			IEnumerable<FrameInfo> result;

			// act
			bool success = FrameInfo.TryParse( "2*bar", out result );

			// assert
			success.Should().BeFalse();
		}

		#endregion

		[TestMethod]
		public void ConstructorCopiesValues()
		{
			// act
			var info = new FrameInfo( 4, 8 );

			// assert
			info.FrameIndex.Should().Be(4);
			info.FrameRepeatCount.Should().Be( 8 );
		}
	}
}
